﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;

namespace AlgoHero.Vista
{
    public abstract class InstrumentoMidi
    {

        private int hmidi;
        private int numeroDeCanal;
        private byte[] data;
        private int volumen;

        [DllImport("winmm.dll")]
        static extern int midiOutOpen(ref int lphMidiOut, int uDevideID, int dwCallback, int dwInstance, UInt32 dwFlags);

        [DllImport("winmm.dll")]
        static extern int midiOutShortMsg(int hMidiOut, UInt32 dwMsg);

        [DllImport("winmm.dll")]
        static extern int midiOutReset(int hMidiOut);

        [DllImport("winmm.dll")]
        static extern int midiOutClose(int hMidiOut);

        public InstrumentoMidi(int numeroDeCanal)
        {
            this.data = new byte[4];
            this.hmidi = 0;
            this.numeroDeCanal = numeroDeCanal;
            this.volumen = 100;
            midiOutOpen(ref this.hmidi, this.numeroDeCanal, 0, 0, 0);
        }

        public void finalize()
        {
            midiOutReset(this.hmidi);
            midiOutClose(this.hmidi);
        }

        public abstract void reproducir(int numeroDeNota, int duracion);

        protected void reproducirAsinc(int numeroDeNota, int duracion)
        {
            if (numeroDeNota < 0 || numeroDeNota > 127)
            {
                throw new ArgumentException("La nota ingresada no es válida.");
            }

            this.data[0] = 0x90;
            this.data[1] = (byte)numeroDeNota;
            this.data[2] = (byte)this.volumen;
            UInt32 msg = BitConverter.ToUInt32(data, 0);
            midiOutShortMsg(hmidi, msg);
            Thread.Sleep(new TimeSpan(0, 0, duracion));
            midiOutReset(this.hmidi);
        }
    }
}
